package com.goti.nettyClient.handler;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.goti.nettyClient.Dispatcher.NettyClientDispatcher;
import com.goti.nettyClient.nettyClient.InitClient;
import com.goti.nettyClient.nettyClient.NettyClient;
import com.goti.nettyClient.protobuf.MsgPro;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.EventLoop;
import io.netty.handler.timeout.ReadTimeoutException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @program: netty_client
 * @package: com.goti.netty_client.handler
 * @description: 客户端分发处理器
 * @author: goti
 * @create: 2019-11-26 11:09
 */
@Component
public class ClientDispatcherHandler extends ChannelInboundHandlerAdapter {


    private static NettyClient nettyClient;
    @Autowired
    private void setNettyClient(NettyClient nettyClient){
        ClientDispatcherHandler.nettyClient=nettyClient;
    }
    Logger logger = LoggerFactory.getLogger(ClientDispatcherHandler.class);

    TimeInterval timer = DateUtil.timer();
    ;


    private static NettyClientDispatcher nettyClientDispatcher;

    @Autowired
    private void setNettyClientDispatcher(NettyClientDispatcher nettyClientDispatcher) {
        ClientDispatcherHandler.nettyClientDispatcher = nettyClientDispatcher;
    }

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        logger.debug("注册事件");
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        logger.debug("取消注册事件");
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        nettyClientDispatcher.setChannelHandlerContext(ctx);
        nettyClientDispatcher.sendMsg("@33", "@333", "@33", "@33");
        logger.debug("连接成功");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        nettyClientDispatcher.removeCtx();
        logger.debug("失去连接");
        nettyClient.doConnect();
//        final EventLoop eventLoop = ctx.channel().eventLoop();
//        eventLoop.schedule(new Runnable() {
//            @Override
//            public void run() {
//                imConnection.connect(ImClientApp.HOST, ImClientApp.PORT);
//            }
//        }, 1L, TimeUnit.SECONDS);
//        super.channelInactive(ctx);
    }

    /**
     * 阅读消息
     *
     * @param ctx
     * @param msg
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        MsgPro.UserMsg userMsg = (MsgPro.UserMsg) msg;

        logger.debug(userMsg.getMsg());
        System.out.println(new Date().getTime());
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        logger.debug("阅读完成");
    }

    /**
     * 一段时间未进行读写操作 回调
     */
    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        logger.debug("超时了");

    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {
        logger.debug("channelWritabilityChanged");


    }

    /**
     * 發生了錯誤
     *
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof ReadTimeoutException) {
            if (ctx.channel().isActive()) {
                ctx.channel().close();
            }
            logger.debug("删除成功");

        }
        logger.debug("错误:" + cause.getMessage());
        //super.exceptionCaught(ctx, cause);
    }

    private void sendMessage(ChannelHandlerContext ctx, String message) {
        MsgPro.UserMsg msg = MsgPro
                .UserMsg
                .newBuilder()
                .setMsg(message)
                .setProCode("111")
                .setMethodType("lol")
                .setVersion("1")
                .build();
        // logger.debug(msg.toByteArray().length);
        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(msg.toByteArray()));
    }

    private MsgPro.UserMsg getMsg(String proCode, String methodType, String version, String message) {
        MsgPro.UserMsg msg = MsgPro
                .UserMsg
                .newBuilder()
                .setMsg(message)
                .setProCode(proCode)
                .setMethodType(methodType)
                .setVersion(version)
                .build();
        return msg;
    }
}
